package org.nacos.provider.converter;

import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import org.nacos.provider.dataobject.ProductDO;
import org.nacos.provider.entity.ProductDTO1;
import org.nacos.provider.entity.ProductDTO2;
import org.nacos.provider.entity.ProductDTO3;

@Mapper
public interface ProductCovertBasic {

	/**
	 * eclipse 需要安装 m2e-apt 插件(找不到实现类错误)
	 * 编译程序 target/generated-sources 文件夹下会自动生成实现类
	 */

	ProductCovertBasic INSTANCE = Mappers.getMapper(ProductCovertBasic.class);

    /**
     * 字段数量类型数量相同，利用工具 BeanUtils 也可以实现类似效果
     */
	ProductDTO1 toConvertVO1(ProductDO productDO);
	
	ProductDO fromConvertEntity1(ProductDTO1 productDTO1);

    /**
     * 字段数量类型相同，数量少：仅能让多的转换成少的，故没有 fromConvertEntity2
     */
	ProductDTO2 toConvertVO2(ProductDO productDO);
	
	/**
	 * 当字段类型不一致时
	 *  1、基本类型及其他们对应的包装类型。 mapstruct 会自动进行拆装箱
	 *  2、基本类型的包装类型和 string 类型之间。 mapstruct 自动进行类型转换
	 *  3、除此之外的类型转换我们可以通过定义表达式来进行指定转换
	 * 当字段名不一致时，指定对应关系，编译后即可实现对应字段的赋值
	 */
    @Mappings({
        @Mapping(target = "desc", expression = "java(org.nacos.provider.util.DateTransform.strToDate(productDO.getDesc()))"),
        @Mapping(source = "prodName", target = "name")
	})
    ProductDTO3 toConvertVO3(ProductDO productDO);
	
    @Mappings({
    	@Mapping(source = "name", target = "prodName")
    })
    ProductDO fromConvertEntity3(ProductDTO3 productDTO3);

	/**
	 * 在 @Mapping 中使用形参的名字去点字段的名
	 * - 支持多参数源映射
	 * - 支持多层嵌套映射
	 */

	/**
	 * 忽略指定属性
	 */
	@Mapping(target = "id", ignore = true)
	ProductDTO1 toIgnoreIdConvertVO1(ProductDO productDO);

	/**
	 * 忽略所有属性
	 */
	@BeanMapping(ignoreByDefault = true)
	@Mapping(source = "prodName", target = "prodName")
	ProductDTO1 toIgnoreAllConvertVO1(ProductDO productDO);

}
